﻿/*
 *Author: Jeff Liu 
 *
 *Under MIT License
 *jebberwocky@gmail.com
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CtpGglGeo.Core;
using CtpGglGeo.Interface;
using CtpGglGeo.Impl;
using CtpGglGeo.Const;

namespace CtpGglGeo.Ggl
{
    /// <summary>
    /// Wrapper classes for geocoding result
    /// Refer to http://code.google.com/apis/maps/documentation/geocoding/index.html
    /// </summary>
    public class GeoObj
    {
        public class AddressComponent
        {
            public String ShortName { set; get; }
            public String LongName { set; get; }
            public List<String> Types { set; get; }
        }

        public class GeometryClass
        {
            public SpotLatLng Location { set; get; }
            public String LocationType { set; get; }
            public SpotLatLng ViewPortSW { set; get; }
            public SpotLatLng ViewPortNE { set; get; }
        }

        public String FormattedAddress { get; set; }
        public List<String> Types { set; get; }
        public GeometryClass Geometry { set; get; }
        public List<AddressComponent> AddressComponents { set; get; }
    }

    /// <summary>
    ///Wrapper classes for geocoding result
    /// Refer to http://code.google.com/apis/maps/documentation/geocoding/index.html
    /// </summary>
    public class GeoResult
    {
        public GeoResult() { }

        public GeoResult(GeoResultStatus status)
        {
            this.Status = status;
        }

        public GeoResultStatus Status;
        public List<GeoObj> Results { get; set; }

        public static GeoResult NotDefinedResult = new GeoResult(GeoResultStatus.UNKNOWN);
        public static GeoResult BlankResult = new GeoResult(GeoResultStatus.ZERO_RESULTS);
    }

    /// <summary>
    /// GetGeoResult with default result format json
    /// @see GetGeoResult
    /// </summary>
    public class Geocoder
    {
        /// <summary>
        /// Get geocoding result, call GetGeoResult(SpotInfo info, string format) with format: "json"
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public GeoResult GetGeoResult(SpotInfo info)
        {
            return GetGeoResult(info, "json");
        }

        /// <summary>
        /// Get geocoding result
        /// </summary>
        /// <param name="info"></param>
        /// <param name="format">"json", "xml" or...</param>
        /// <returns></returns>
        public GeoResult GetGeoResult(SpotInfo info, string format)
        {
            if (info == null)
                return GeoResult.BlankResult;
            if (string.Empty.Equals(info.Address)&&SpotLatLng.NOT_DEFINE_LAT_LNG.Equals(info.LatLng))
                return GeoResult.BlankResult;

            IGeoResultParser parser = null;
            if ("json".Equals(format))
                parser = new JsonGeoResultParser();
            else
                throw new NotSupportedException();

            String resultText = GoogleGeoAPI.SendRequest(info, format);
            /*parse the resultText to GeoResult Object*/
            GeoResult result = parser.Parse(resultText);
            return result;
        }
    }
}
